//
//  DateTime.m
//  SimulacraDB
//
//  Created by Andre Cohen on 8/30/08.
//  Copyright 2008 __MyCompanyName__. All rights reserved.
//

#import "DateTime.h"


@implementation DateTime

@synthesize year, zone, mSecond;
@synthesize month, day, hour, minute, second;
@synthesize isAC;

+ (id)createFromNSDate:(NSDate *)date {
	return [[[DateTime alloc] initFromString:[date description]] autorelease];
}

+ (id)createFromString:(NSString *)date {
	return [[[DateTime alloc] initFromString:date] autorelease];
}

- (id)init {
	[super init];
	[self setYear:0];
	[self setMonth:0];
	[self setDay:0];
	[self setHour:0];
	[self setMinute:0];
	[self setSecond:0];
	[self setMSecond:0];
	[self setIsAC:YES];
	[self setZone:0];
	return self;
}

- (id)initFromString:(NSString *)dateTime {
	[self init];
	
	if(dateTime==nil)
		return self;
	
	NSArray *parts = [dateTime componentsSeparatedByString:@" "];

	int i;
	for(i=0;i<[parts count];i++){
		if([[parts objectAtIndex:i] length]==10)
			[self setDateFromString:[parts objectAtIndex:i]];
		else if([[parts objectAtIndex:i] length]==8)
			[self setTimeFromString:[parts objectAtIndex:i]];
		else if([[parts objectAtIndex:i] length]==5)
			[self setTimeZoneFromString:[parts objectAtIndex:i]];
		else if([[parts objectAtIndex:i] length]==2)
			[self setEraFromString:[parts objectAtIndex:i]];
		else
			return nil;
	}
	return self;
}

- (double)dateStamp {
	double s = [self day] + ([self month]*100) + ([self year]*10000);
	if([self isAC])
		return s;
	return -1*s;
}

- (double)timeStamp {
	return [self mSecond] + [self second] + ([self minute]*100) + ([self hour]*10000);
}

- (void)setDateFromStamp:(double)date {
	if(date<0)
		[self setIsAC:NO];
	date = fabs(date);
	[self setYear:floor(date/10000)];
	[self setMonth:floor((date-(floor(date/1000)*1000))/100)];
	[self setDay:date-floor(date/100)*100];
}

- (void)setTimeFromStamp:(double)time {
	[self setHour:floor(time/10000)];
	[self setMinute:floor((time-floor(time/10000)*10000)/100)];
	[self setSecond:floor(time-floor(time/100)*100)];
	[self setMSecond:(time-floor(time))*1000];
}

- (void)setDateFromString:(NSString *)date {
	NSArray *parts = [date componentsSeparatedByString:@"-"];
	if([parts count]<3)
		return;
	[self setYear:[[parts objectAtIndex:0] intValue]];
	[self setMonth:(char)[[parts objectAtIndex:1] intValue]];
	[self setDay:(char)[[parts objectAtIndex:2] intValue]];
}

- (void)setTimeFromString:(NSString *)time {
	NSArray *parts = [time componentsSeparatedByString:@":"];
	if([parts count]<3)
		return;
	[self setHour:[[parts objectAtIndex:0] intValue]];
	[self setMinute:(char)[[parts objectAtIndex:1] intValue]];
	if([[parts objectAtIndex:2] length]>2){
		NSArray *s = [[parts objectAtIndex:2] componentsSeparatedByString:@"."];
		[self setSecond:(char)[[s objectAtIndex:0] intValue]];
		[self setMSecond:(char)[[s objectAtIndex:0] intValue]];
	}else{
		[self setSecond:(char)[[parts objectAtIndex:2] intValue]];
	}
}

- (void)setTimeZoneFromString:(NSString *)timeZone {
	[self setZone:[timeZone intValue]];
}

- (void)setEraFromString:(NSString *)era{
	isAC = [era isEqualToString:@"AC"];
}

- (NSComparisonResult)compare:(NSObject *)object {
	DateTime *b = (DateTime *)object;
	if([self dateStamp]!=[b dateStamp])
		return ([self dateStamp]-[b dateStamp]>0) ? NSOrderedDescending : NSOrderedAscending;
	if([self timeStamp]!=[b timeStamp])
		return ([self timeStamp]-[b timeStamp]>0) ? NSOrderedDescending : NSOrderedAscending;
	return NSOrderedSame;
}

- (NSString *)description {
	return [NSString stringWithFormat:@"%@ %@ %@ %@",[self dateDescription],[self timeDescription],[self zoneDescription],[self eraDescription]];
}

- (NSString *)dateDescription {
	return [NSString stringWithFormat:@"%04d-%02d-%02d",[self year],[self month],[self day]];
}
- (NSString *)timeDescription {
	return [NSString stringWithFormat:@"%02d:%02d:%02d.%03d",[self hour],[self minute],[self second],[self mSecond]];
}
- (NSString *)zoneDescription {
	return [NSString stringWithFormat:@"%d",[self zone]];
}
- (NSString *)eraDescription {
	if(isAC)
		return @"AC";
	return @"BC";
}

@end
